package com.agent.platform.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.agent.platform.dto.AgentHeartbeatDTO;
import com.agent.platform.dto.AgentRegisterDTO;
import com.agent.platform.entity.AgentInfo;
import com.agent.platform.exception.BusinessException;
import com.agent.platform.mapper.AgentInfoMapper;
import com.agent.platform.vo.AgentVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class AgentService {
    
    private final AgentInfoMapper agentInfoMapper;
    
    public Map<String, String> register(AgentRegisterDTO dto) {
        String agentId = "agent_" + IdUtil.fastSimpleUUID();
        
        AgentInfo agent = new AgentInfo();
        BeanUtil.copyProperties(dto, agent);
        agent.setAgentId(agentId);
        agent.setStatus("ONLINE");
        agent.setHeartbeatTime(LocalDateTime.now());
        
        agentInfoMapper.insert(agent);
        
        Map<String, String> result = new HashMap<>();
        result.put("agentId", agentId);
        result.put("token", IdUtil.fastSimpleUUID());
        return result;
    }
    
    public void unregister(String agentId) {
        AgentInfo agent = getByAgentId(agentId);
        agentInfoMapper.deleteById(agent.getId());
    }
    
    public void heartbeat(AgentHeartbeatDTO dto) {
        AgentInfo agent = getByAgentId(dto.getAgentId());
        agent.setHeartbeatTime(LocalDateTime.now());
        if (dto.getStatus() != null) {
            agent.setStatus(dto.getStatus());
        }
        agentInfoMapper.updateById(agent);
    }
    
    public Page<AgentVO> list(Integer current, Integer size, String agentType, String status) {
        Page<AgentInfo> page = new Page<>(current, size);
        LambdaQueryWrapper<AgentInfo> wrapper = new LambdaQueryWrapper<>();
        
        if (agentType != null && !agentType.isEmpty()) {
            wrapper.eq(AgentInfo::getAgentType, agentType);
        }
        if (status != null && !status.isEmpty()) {
            wrapper.eq(AgentInfo::getStatus, status);
        }
        wrapper.orderByDesc(AgentInfo::getCreateTime);
        
        Page<AgentInfo> result = agentInfoMapper.selectPage(page, wrapper);
        Page<AgentVO> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
        voPage.setRecords(result.getRecords().stream()
            .map(agent -> BeanUtil.copyProperties(agent, AgentVO.class))
            .toList());
        return voPage;
    }
    
    public AgentVO getDetail(String agentId) {
        AgentInfo agent = getByAgentId(agentId);
        return BeanUtil.copyProperties(agent, AgentVO.class);
    }
    
    public void checkOffline() {
        LocalDateTime timeout = LocalDateTime.now().minusMinutes(5);
        LambdaQueryWrapper<AgentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AgentInfo::getStatus, "ONLINE")
               .lt(AgentInfo::getHeartbeatTime, timeout);
        
        List<AgentInfo> agents = agentInfoMapper.selectList(wrapper);
        for (AgentInfo agent : agents) {
            agent.setStatus("OFFLINE");
            agentInfoMapper.updateById(agent);
        }
    }
    
    private AgentInfo getByAgentId(String agentId) {
        LambdaQueryWrapper<AgentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AgentInfo::getAgentId, agentId);
        AgentInfo agent = agentInfoMapper.selectOne(wrapper);
        if (agent == null) {
            throw new BusinessException("智能体不存在");
        }
        return agent;
    }
}
